﻿using SketchUpAPI.NET.Enums;
using SketchUpAPI.NET.Objects;
using SketchUpAPI.NET.SketchUp.Exception;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;
using System.Xml.Linq;

namespace SketchUpAPI.NET.Objects
{
    /// <summary>
    /// 物件集
    /// </summary>
    /// <remarks>该类型对应 SketchUPAPI 中的 SUEntitiesRef</remarks>
    public class EntityTable : ObjectBase
    {
        #region API 函数
        /// <summary>
        /// 清空物件集
        /// </summary>
        /// <param name="entities"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesClear(IntPtr entities);

        /// <summary>
        /// 向物件表中添加一个物体
        /// </summary>
        /// <param name="entities">物件表</param>
        /// <param name="geometryInput"><see cref="GeometryInput"/> 物体</param>
        /// <param name="weld"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesFill(IntPtr entities, IntPtr geometryInput, bool weld);

        /// <summary>
        /// 获取物件集的外边界
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="bbox"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetBoundingBox(IntPtr entities, ref BoundingBox3D bbox);

        /// <summary>
        /// 获取物件集的外边界，以  维度Latidue, 精度Longitude , 海拔 Altitude 计算
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="bbox"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetBoundingBoxLLA(IntPtr entities, ref BoundingBox3D bbox);

        /// <summary>
        /// 获取面的个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumFaces(IntPtr entities, out long count);

        /// <summary>
        /// 获取全部的面
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len">面的个数</param>
        /// <param name="faces"><see cref="Face"/>[] 面</param>
        /// <param name="realcount">实际个数</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetFaces(IntPtr entities, long len, IntPtr[] faces, out long realcount);

        /// <summary>
        /// 获取曲线的个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count">返回，曲线个数</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumCurves(IntPtr entities, out long count);

        /// <summary>
        /// 获取全部曲线
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len">曲线个数</param>
        /// <param name="curves"><see cref="Curve"/>[] 全部曲线</param>
        /// <param name="realcount">实际个数</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetCurves(IntPtr entities, long len, IntPtr[] curves, out long realcount);

        /// <summary>
        /// 圆弧个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumArcCurves(IntPtr entities, out long count);

        /// <summary>
        /// 获取全部圆弧
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="arccurves"><see cref="Arc"/>[] 圆弧</param>
        /// <param name="realcount">实际个数</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetArcCurves(IntPtr entities, long len, IntPtr[] arccurves, out long realcount);

        /// <summary>
        /// 参考点的个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumGuidePoints(IntPtr entities, out long count);

        /// <summary>
        /// 获取全部参考点
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="guide_points"><see cref="GuidePoint"/>[] 引导点</param>
        /// <param name="realcount">实际个数</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetGuidePoints(IntPtr entities, long len, IntPtr[] guide_points, out long realcount);

        /// <summary>
        /// 获取参考线的个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumGuideLines(IntPtr entities, out long count);

        /// <summary>
        /// 获取全部参考线
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="guide_lines"><see cref="GuideLine"/>[] 参考线</param>
        /// <param name="realcount">实际个数</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetGuideLines(IntPtr entities, long len, IntPtr[] guide_lines, out long realcount);

        /// <summary>
        /// 获取边缘个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumEdges(IntPtr entities, bool aloneOnly, out long count);

        /// <summary>
        /// 获取全部边缘
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <param name="edges"></param>
        /// <param name="realCount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetEdges(IntPtr entities, bool aloneOnly, long count, IntPtr[] edges, out long realCount);

        /// <summary>
        /// 获取多段线个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumPolyline3ds(IntPtr entities, out long count);

        /// <summary>
        /// 获取全部多段线
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="lines"><see cref="Polyline3D"/>[] 多段线</param>
        /// <param name="count">实际个数</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetPolyline3ds(IntPtr entities, long len, IntPtr[] lines, out long count);

        /// <summary>
        /// 添加边缘
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="edges"><see cref="Edge"/>[] 边缘</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesAddEdges(IntPtr entities, long len, IntPtr[] edges);

        /// <summary>
        /// 添加曲线
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <param name="curves"><see cref="Curve"/>[] 曲线</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesAddCurves(IntPtr entities, long count, IntPtr[] curves);

        /// <summary>
        /// 添加圆弧
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <param name="arcCurves"><see cref="Arc"/>[] 圆弧</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesAddArcCurves(IntPtr entities, long count, IntPtr[] arcCurves);

        /// <summary>
        /// 添加参考点
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="guide_points"><see cref="GuidePoint"/>[] 参考点</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesAddGuidePoints(IntPtr entities, long len, IntPtr[] guide_points);

        /// <summary>
        /// 添加参考线
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="guide_lines"><see cref="GuideLine"/>[] 参考线</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesAddGuideLines(IntPtr entities, long len, IntPtr[] guide_lines);

        /// <summary>
        /// 添加一个群组
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="group"><see cref="Group"/> 群组</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesAddGroup(IntPtr entities, IntPtr group);

        /// <summary>
        /// 添加图像
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="image"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesAddImage(IntPtr entities, IntPtr image);

        /// <summary>
        /// 添加一个组件实例
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="instance"><see cref="ComponentInstance"/></param>
        /// <param name="name"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesAddInstance(IntPtr entities, IntPtr instance, [MarshalAs(UnmanagedType.LPUTF8Str)] string name);

        /// <summary>
        /// 添加截平面
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="section_planes"><see cref="SectionPlane"/>[] 截面</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesAddSectionPlanes(IntPtr entities, long len, IntPtr[] section_planes);

        /// <summary>
        /// 添加文字
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="texts"><see cref="Text"/>[] 文字</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesAddTexts(IntPtr entities, long len, IntPtr[] texts);

        /// <summary>
        /// 获取物件集中群组的个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumGroups(IntPtr entities, out long count);

        /// <summary>
        /// 获取物件集中全部群组
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="groups"></param>
        /// <param name="realCount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetGroups(IntPtr entities, long len, IntPtr[] groups, out long realCount);

        /// <summary>
        /// 获取图片个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumImages(IntPtr entities, out long count);

        /// <summary>
        /// 获取全部图片
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="images"><see cref="Image"/>[] 图片</param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetImages(IntPtr entities, long len, IntPtr[] images, out long realcount);

        /// <summary>
        /// 获取组件个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumInstances(IntPtr entities, out long count);

        /// <summary>
        /// 获取全部组件实例
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="instances"><see cref="ComponentInstance"/>[] 组件实例</param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetInstances(IntPtr entities, long len, IntPtr[] instances, out long realcount);

        /// <summary>
        /// 获取截面个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumSectionPlanes(IntPtr entities, out long count);

        /// <summary>
        /// 获取全部截面
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="section_planes"><see cref="SectionPlane"/>[] 截面</param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetSectionPlanes(IntPtr entities, long len, IntPtr[] section_planes, out long realcount);

        /// <summary>
        /// 获取文字个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumTexts(IntPtr entities, out long count);

        /// <summary>
        /// 获取全部文字
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="texts"><see cref="Text"/>[] 文字</param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetTexts(IntPtr entities, long len, IntPtr[] texts, out long realcount);

        /// <summary>
        /// 获取标注个数
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetNumDimensions(IntPtr entities, out long count);

        /// <summary>
        /// 获取全部标注
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="dimensions"><see cref="Dimension"/>[] 标注（API中不是数组，但是根据函数功能这里应该是数组，请在测试中确认）</param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetDimensions(IntPtr entities, long len, IntPtr[] dimensions, out long realcount);

        /// <summary>
        /// 应用变换到一组物体上
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="elements"><see cref="Entity"/>[] 要应用变换到的物体</param>
        /// <param name="trans"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesTransform(IntPtr entities, long len, IntPtr[] elements, Transformation trans);

        /// <summary>
        /// 为一组物体分别设置变换，既物体和变换一一对应
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="elements"><see cref="Entity"/>[]</param>
        /// <param name="tranforms"><see cref="Transformation"/>[]</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesTransformMultiple(IntPtr entities, long len, IntPtr[] elements, Transformation[] tranforms);

        /// <summary>
        /// 删除物体
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="len"></param>
        /// <param name="elements"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesErase(IntPtr entities, long len, IntPtr[] elements);

        /// <summary>
        /// 物件表是否为递归空，既不仅没有物体，所包含的组件定义里也没有物体
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="is_empty"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesIsRecursivelyEmpty(IntPtr entities, out bool is_empty);

        /// <summary>
        /// 是否有活动截平面，或者嵌套组件有活动截平面
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="has_section_cuts"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesHasSectionCuts(IntPtr entities, out bool has_section_cuts);

        /// <summary>
        /// 将集合中指定类型的物体添加到物件表
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="type"></param>
        /// <param name="list"><see cref="EntityList"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesEntityListFill(IntPtr entities, SUType type, IntPtr list);

        /// <summary>
        /// 将边连成曲线
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="num_edges">边的个数</param>
        /// <param name="edges"><see cref="Edge"/>[] 边</param>
        /// <param name="list"><see cref="EntityList"/> 用于返回曲线</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesWeld(IntPtr entities, long num_edges, IntPtr[] edges, IntPtr list);

        /// <summary>
        /// 获取拥有该物件集的物体
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="parent"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetParent(IntPtr entities, ref EntitiesParent parent);

        /// <summary>
        /// 获取活动的截面
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="section_plane"><see cref="SectionPlane"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesGetActiveSectionPlane(IntPtr entities, out IntPtr section_plane);

        /// <summary>
        /// 设置激活的截平面
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="section_plane"><see cref="SectionPlane"/></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUEntitiesSetActiveSectionPlane(IntPtr entities, IntPtr section_plane);
        #endregion

        /// <summary>
        /// 获取拥有该物件集的物体
        /// </summary>
        public EntitiesParent Parent
        {
            get
            {
                EntitiesParent e = new EntitiesParent();
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetParent(Id, ref e));
                return e;
            }
        }

        /// <summary>
        /// 是否为空
        /// </summary>
        /// <remarks>物件表是否为递归空，既不仅没有物体，所包含的组件定义里也没有物体</remarks>
        public bool IsRecursivelyEmpty
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesIsRecursivelyEmpty(Id, out bool em));
                return em;
            }
        }

        /// <summary>
        /// 是否有活动截平面，或者嵌套组件有活动截平面
        /// </summary>
        public bool HasSectionCuts
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesHasSectionCuts(Id, out bool has));
                return has;
            }
        }

        /// <summary>
        /// 获取截平面
        /// </summary>
        public SectionPlane ActiveSectionPlane
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetActiveSectionPlane(Id, out IntPtr id));
                return new SectionPlane(id);
            }
            set
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesSetActiveSectionPlane(Id, value.Id));
            }
        }

        /// <summary>
        /// 获取边界框
        /// </summary>
        public BoundingBox3D BoundingBox
        {
            get
            {
                BoundingBox3D b = new BoundingBox3D();
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetBoundingBox(Id, ref b));
                return b;
            }
        }

        /// <summary>
        /// 获取LLA边界
        /// </summary>
        /// <remarks>既：维度Latidue, 精度Longitude , 海拔 Altitude </remarks>
        public BoundingBox3D BoundingBoxLLA
        {
            get
            {
                BoundingBox3D b = new BoundingBox3D();
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetBoundingBoxLLA(Id, ref b));
                return b;
            }
        }

        /// <summary>
        /// 获取全部组件实例
        /// </summary>
        public List<ComponentInstance> Components
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumInstances(Id, out long count));
                IntPtr[] pts = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetInstances(Id, count, pts, out long realcount));
                return pts.Select(i => new ComponentInstance(i)).ToList();
            }
        }

        /// <summary>
        /// 全部群组
        /// </summary>
        public List<Group> Groups
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumGroups(Id, out long Count));
                IntPtr[] ptrs = new IntPtr[Count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetGroups(Id, Count, ptrs, out long realCount));

                return ptrs.Select(pt => new Group(pt)).ToList();
            }
        }

        /// <summary>
        /// 全部边缘
        /// </summary>
        public List<Edge> Edges
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumEdges(Id, false, out long count));
                IntPtr[] ptrs = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetEdges(Id, false, count, ptrs, out long realCount));
                return ptrs.Select(pt => new Edge(pt)).ToList();
            }
        }

        /// <summary>
        /// 独立边缘
        /// </summary>
        public List<Edge> EdgesStandalone
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumEdges(Id, true, out long count));
                IntPtr[] ptrs = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetEdges(Id, true, count, ptrs, out long realCount));
                return ptrs.Select(pt => new Edge(pt)).ToList();
            }
        }

        /// <summary>
        /// 全部面数据
        /// </summary>
        public List<Face> Faces
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumFaces(Id, out long count));
                IntPtr[] pts = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetFaces(Id, count, pts, out long realCount));
                return pts.Select(i => new Face(i)).ToList();
            }
        }

        /// <summary>
        /// 曲线
        /// </summary>
        public List<Curve> Curves
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumCurves(Id, out long count));
                IntPtr[] pts = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetCurves(Id, count, pts, out long realCount));
                return pts.Select(i => new Curve(i)).ToList();
            }
        }

        /// <summary>
        /// 圆弧
        /// </summary>
        public List<Arc> Arcs
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumArcCurves(Id, out long count));
                IntPtr[] pts = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetArcCurves(Id, count, pts, out long realCount));
                return pts.Select(i => new Arc(i)).ToList();
            }
        }

        /// <summary>
        /// 获取参考点
        /// </summary>
        public List<GuidePoint> GuidePoints
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumGuidePoints(Id, out long count));
                IntPtr[] pts = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetGuidePoints(Id, count, pts, out long realcount));
                return pts.Select(i => new GuidePoint(i)).ToList();
            }
        }

        /// <summary>
        /// 获取参考线
        /// </summary>
        public List<GuideLine> GuideLines
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumGuideLines(Id, out long count));
                IntPtr[] pts = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetGuideLines(Id, count, pts, out long realcount));
                return pts.Select(i => new GuideLine(i)).ToList();
            }
        }

        /// <summary>
        /// 多段线
        /// </summary>
        public List<Polyline3D> Polylines
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumPolyline3ds(Id, out long count));
                IntPtr[] intPtrs = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetPolyline3ds(Id, count, intPtrs, out long realcount));
                return intPtrs.Select(i => new Polyline3D(i)).ToList();
            }
        }

        /// <summary>
        /// 图片
        /// </summary>
        public List<Image> Images
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumImages(Id, out long count));
                IntPtr[] intPtrs = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetImages(Id, count, intPtrs, out long realcount));
                return intPtrs.Select(i => new Image(i)).ToList();
            }
        }

        /// <summary>
        /// 截面
        /// </summary>
        public List<SectionPlane> SectionPlanes
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumSectionPlanes(Id, out long count));
                IntPtr[] intPtrs = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetSectionPlanes(Id, count, intPtrs, out long realcount));
                return intPtrs.Select(i => new SectionPlane(i)).ToList();
            }
        }

        /// <summary>
        /// 文字
        /// </summary>
        public List<Text> Texts
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumTexts(Id, out long count));
                IntPtr[] intPtrs = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetTexts(Id, count, intPtrs, out long realcount));
                return intPtrs.Select(i => new Text(i)).ToList();
            }
        }

        /// <summary>
        /// 尺寸标注
        /// </summary>
        public List<Dimension> Dimensions
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetNumDimensions(Id, out long count));
                IntPtr[] intPtrs = new IntPtr[count];
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesGetDimensions(Id, count, intPtrs, out long realcount));
                return intPtrs.Select(i => new Dimension(i)).ToList();
            }
        }

        internal EntityTable(IntPtr id)
        {
            Id = id;
        }

        /// <summary>
        /// 清空物件集
        /// </summary>
        public void Clear()
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesClear(Id));
        }

        /// <summary>
        /// 添加一个物体
        /// </summary>
        /// <param name="geoInput"></param>
        /// <param name="weld"></param>
        /// <returns></returns>
        public void Add(GeometryInput geoInput, bool weld, bool isGroup = false)
        {
            if (isGroup)
            {
                Group gr = new Group();
                gr.Entities.Add(geoInput, weld, false);
                Add(gr);
            }
            else
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesFill(Id, geoInput.Id, weld));
            }
        }

        /// <summary>
        /// 添加一个组件实例
        /// </summary>
        /// <param name="instance"></param>
        /// <returns></returns>
        public void Add(ComponentInstance instance, string name = null)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesAddInstance(Id, instance.Id, name));
        }

        /// <summary>
        /// 添加一个群组
        /// </summary>
        /// <param name="group"></param>
        public void Add(Group group)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesAddGroup(Id, group.Id));
        }

        /// <summary>
        /// 添加曲线
        /// </summary>
        /// <param name="curve"></param>
        public void Add(params Curve[] curves)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesAddCurves(Id, curves.Length, curves.Select(cr => cr.Id).ToArray()));
        }

        /// <summary>
        /// 添加圆弧
        /// </summary>
        /// <param name="curve"></param>
        public void Add(params Arc[] curves)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesAddArcCurves(Id, curves.Length, curves.Select(cr => cr.Id).ToArray()));
        }

        /// <summary>
        /// 添加边缘
        /// </summary>
        /// <param name="edges"></param>
        public void Add(params Edge[] edges)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesAddEdges(Id, edges.Length, edges.Select(cr => cr.Id).ToArray()));
        }

        /// <summary>
        /// 添加参考点
        /// </summary>
        /// <param name="guidePoints"></param>
        public void Add(params GuidePoint[] guidePoints)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesAddGuidePoints(Id, guidePoints.LongLength, guidePoints.Select(g => g.Id).ToArray()));
        }

        /// <summary>
        /// 添加参考线
        /// </summary>
        /// <param name="guideLines"></param>
        public void Add(params GuideLine[] guideLines)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesAddGuideLines(Id, guideLines.LongLength, guideLines.Select(g => g.Id).ToArray()));
        }

        /// <summary>
        /// 添加图像
        /// </summary>
        /// <param name="images"></param>
        public void Add(params Image[] images)
        {
            foreach (var item in images)
            {
                SketchUpExceptionHelper.ThrowSUResult(SUEntitiesAddImage(Id, item.Id));
            }
        }

        /// <summary>
        /// 添加截面
        /// </summary>
        /// <param name="sectionPlanes"></param>
        public void Add(params SectionPlane[] sectionPlanes)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesAddSectionPlanes(Id, sectionPlanes.LongLength, sectionPlanes.Select(i => i.Id).ToArray()));
        }

        /// <summary>
        /// 添加文字
        /// </summary>
        /// <param name="texts"></param>
        public void Add(params Text[] texts)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesAddTexts(Id, texts.LongLength, texts.Select(i => i.Id).ToArray()));
        }

        /// <summary>
        /// 将集合中指定类型的物体添加到物件集
        /// </summary>
        /// <param name="type"></param>
        /// <param name="list"></param>
        public void Add(SUType type, EntityList list)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesEntityListFill(Id, type, list.Id));
        }

        /// <summary>
        /// 将一个变换应用到多个物体上
        /// </summary>
        /// <param name="trans"></param>
        /// <param name="entities"></param>
        public void ApplyTransform(Transformation trans, params Entity[] entities)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesTransform(Id, entities.LongLength, entities.Select(e => e.Id).ToArray(), trans));
        }

        /// <summary>
        /// 将一组变换一一对应的应用到一组物体上
        /// </summary>
        /// <param name="trans"></param>
        /// <param name="entities"></param>
        public void ApplyTransform(Transformation[] trans, Entity[] entities)
        {
            if (trans.Length != entities.Length) throw new ArgumentException("变换个数与物体个数不相等");
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesTransformMultiple(Id, trans.LongLength, entities.Select(e => e.Id).ToArray(), trans));
        }

        /// <summary>
        /// 删除物体
        /// </summary>
        /// <param name="entities"></param>
        public void Delete(params Entity[] entities)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesErase(Id, entities.LongLength, entities.Select(e => e.Id).ToArray()));
        }

        /// <summary>
        /// 将边缘连接为曲线
        /// </summary>
        /// <remarks>曲线不会相交</remarks>
        /// <param name="edges"></param>
        /// <returns>返回物件表，用于储存连接成的 <see cref="Curve"/></returns>
        public EntityList ConnectEdgeToCurve(params Edge[] edges)
        {
            EntityList list = new EntityList();
            SketchUpExceptionHelper.ThrowSUResult(SUEntitiesWeld(Id, edges.LongLength, edges.Select(e => e.Id).ToArray(), list.Id));
            return list;
        }
    }
}